"""
@author: zjc
@file: auth.py
@time: 2023/3/13 20:23
"""
from flask import request,current_app
from libs.response import response_data
import time
from model.userdb.userinfo import ApiToken
from hashlib import md5
from itsdangerous import TimedJSONWebSignatureSerializer as TJS
from itsdangerous import BadSignature, SignatureExpired
from libs.error_code import TokenFailException


def login(func):
    def inner(*args,**kwargs):
        api_flag=request.args.get("api")
        if str(api_flag)=="1":
            result=api_auth()
        else:
            result=user_auth()
        if result:
            result=func(*args,**kwargs)
            return result
        else:
            return response_data(code=3,message="认证失败"),401
    return inner

def api_auth():
    params = request.args  #客户端url传递过来的参数
    appid = params.get("appid")
    salt = params.get("salt")  # 盐值
    sign = params.get("sign")  # 签名
    timestamp = params.get("timestamp")  # 时间戳

    if time.time() - float(timestamp) > 600:
       return False

    api_token = ApiToken.query.filter_by(appid=appid).first()
    if not api_token:
        return False

    if not has_permission(api_token, request.path, request.method.lower()):
        return False

    secretkey = api_token.secretkey
    user_sign = appid + salt + secretkey + timestamp

    m1 = md5()
    m1.update(user_sign.encode(encoding="utf-8"))
    if sign != m1.hexdigest():
        return False
    else:
        return True


def has_permission(api_token, url, method):
    mypermission = method + url
    all_permission = [permission.method_type + permission.url
                      for permission in api_token.manage]

    if mypermission in all_permission:
        return True
    else:
        return False

def user_auth():
    print("user auth.....")
    token=request.headers.get("token")
    if token:
        s=TJS(current_app.config["SECRET_KEY"])
        try:
            data=s.loads(token)
        except BadSignature:
            raise TokenFailException
        except SignatureExpired:
            raise RuntimeError("token过期")
        return data
    else:
       raise RuntimeError("没有拿到token")


def create_token(uid):
    s = TJS(current_app.config["SECRET_KEY"], expires_in=current_app.config["EXPIRES_IN"])
    token = s.dumps({"uid":uid}).decode("ascii")
    return token